/*
 *  HOM.h
 *  HigherOrderMessaging
 *
 *  Created by Ofri Wolfus on 10/09/05.
 *  Copyright 2005 Ofri Wolfus. All rights reserved.
 *
 */

/*!
 * @header HOM
 * HOM defines the general HOM protocol.
 * @copyright Created by Ofri Wolfus on 10/09/05. Copyright 2004-2005 Ofri Wolfus. All rights reserved.
 * @updated 2005-09-10
 * @version 0.1
 */


/*!
 * @protocol HOM
 * @abstract HOM defines the basic higher object messaging message that all classes should implement.
 */
@protocol HOM

/*!
 * @method ifResponds
 * @abstract Sends the argument message only if the receiver reponds to it.
 * @discussion Instead of writing if ([receiver respondsToSelector:sel]) [receiver sel], simply use [[receiver ifResponds] sel].
 * This makes the code cleaner and easier to read.
 * @result If the result is an object then it'll be returned. Otherwise, HOMObjCValue inctance containing the result will be returned.
 */
- (id)ifResponds;

/*!
 * @method do
 * @abstract Performs the argument message with changing arguments values.
 * @discussion The do HOM must be used in conjunction with the each HOM like this:
 * <code>[[myObject do] addObjects:[objects each] forKeys:[keys each]]</code>
 * The argument message will then be invoked several times with all the values of objects and keys.
 * Each invocation of the argument message, uses new value from the iterated argument.
 * Once an iterated argument has no more values, the last value will be used for all next invocations.
 * Any "normal" argument (not iterated) will be left unchanged.
 * See Higher_Order_Messaging_OOPSLA_2005.pdf for more info.
 */
- (id)do;

/*!
 * @method do
 * @abstract Performs the argument message in a new thread.
 * @discussion Detaches a new thread, sets up an autorelease pool, and then performs the argument message.
 * @result Returns the receiver (self).
 */
- (id)async;

/*!
 * @method mainPerformAndWait:
 * @abstract Performs the argument message in the main thread.
 * @discussion Instead of calling performSelectorOnMainThread:withObject:waitUntilDone: this HOM allows you to do the same, but with as many argument you wish.
 */
- (id)mainPerformAndWait:(BOOL)waitUntilDone;

/*!
 * @method mainPerform
 * @abstract Does the same as -mainPerformAndWait: but without waiting.
 */
- (id)mainPerform;

/*!
 * @method ifNotNil
 * @abstract Performs the prefix message only if all its arguments are not nil.
 */
- (id)ifNotNil;

@end

